	NAME	ZXMAIN
	TITLE	ZX65  VER 2.1  8/80  RMK
;
; V 2.1 OF ZX65 IS MODIFIED TO BE LINKED AT ASSEMBLY
; TIME WITH ZXLD V 2.1.  THIS COMBINATION IS TOTALLY
; RELOCATABLE, AND WILL FUNCTION UNDER ANY CPM 1.4
; SYSTEM SIZE.  FORMAT IS FOR SD SYSTEMS ASSEMBLER
; V 3.3 AND LINKER V 3.0
;
; V 2.1 INCLUDES ALL PREVIOUS MODS PLUS CORRECTED
; JSR/JMP/RTS FUNCTIONS.
;
	GLOBAL	RELBAS
;
BASE	EQU	$
HOST    EQU     BASE+0F00H	; HOST SYSTEM CBIOS
SYSTK	EQU	HOST		; SYSTEM STACK
CPWRM	EQU	HOST+3		; CP/M COLD ST
CONST	EQU	HOST+6		; HOST SYSTEM INPUT TEST
CONIN   EQU     HOST+9		; HOST SYSTEM CONS IN
CONOUT  EQU     HOST+0CH	; HOST SYSTEM CONS OUT
HOME	EQU	HOST+18H	; DRIV HOME
SETDRV	EQU	HOST+1BH	; SELECT DRVE
SETTRK	EQU	HOST+1EH	; SELECT TRACK
SETSEC	EQU	HOST+21H	; SELECT SECTOR
SETBUF	EQU	HOST+24H	; SET XFER ADDRESS
READ	EQU	HOST+27H	; READ A SECTOR
WRITE	EQU	HOST+2AH	; WRITE A SECTOR
;
RELBAS	LD	SP,SYSTK
	LD	C,1
	CALL	DRVS		; ACTIVATE DRV B
	CALL	HOMB		; AND INIT IT
	LD      IY,INTRO
	CALL    PRTXT		; PRINT HEADER
	CALL	CRLF
;
; COMMAND LEVEL...RETURN HERE FROM ANY POINT IN PGM
;
CMND    LD      HL,CMND
	PUSH    HL		; RET ADDR ON STACK
	CALL    CRLF
	CALL    PROM
	CALL    GETCHR		; GET COMMAND
	CP	'E'
	JP	Z,EXAM		; EXAM MEMORY
	CP	'M'
	JP	Z,SUBM		; SUB MEMORY
	LD	IX,VREG		; FOR SIMX
	CP      'B'
	JR      Z,BRKP-$	; RUN TO BREAKPOINT
	CP	'C'
	JP	Z,RGSTR		; DSPLY/MODIFY CPU REGS
	CP      'G'
	JP	Z,RUN		; RUN FROM NPC
	CP	'T'
	JR	Z,MULTX-$	; TRACE/DISPLAY N STEPS
	CP      ' '
	JR      Z,EXONE-$	; EX ONE INSTR & STOP
	LD	IX,BUFFR	; FOR DOS
	CP      'D'
	JP      Z,PDIR		; DOS DIR
	CP      'I'
	JP      Z,INIT		; DOS INITIALIZE
	CP      'K'
	JP      Z,KILL		; DOS ERASE
	CP      'L'
	JP      Z,LOAD		; DOS LOADER
	CP	'R'
	JP	Z,LDGO		; LOAD AND RUN PGM
	CP      'S'
	JP      Z,SAVE		; DOS SAVER
	LD	C,'?'
	CALL	PRNC		; INVALID COMMAND
	JR	CMND-$
;
; EXECUTE N STEPS
;
MULTX	LD	IY,MLTMSG
	CALL	PRTXT
	CALL	GETWRD		; GET N
	LD	A,E
	JR      NZ,DOMULT-$
EXONE   LD      A,1		; EXECUTE 1 STEP
;
; EXECUTE # STEPS IN A
;
DOMULT  LD      (NSTEPS),A      ; STORE N IN TEMP
	CALL    STEP		; EXEC & DSPLY INSTR
	CALL    DSPLY
	LD      A,(NSTEPS)
	DEC     A
	RET	Z
	PUSH	AF
	LD	BC,DLYCON	; DELAY FOR VIEWING
DOLP	DEC	BC
	LD	A,B
	OR	C
	JR	NZ,DOLP-$
	POP	AF
	JR	DOMULT-$
;
; RUN WITHOUT DISPLAY TO BREAKPOINT
;
BRKP	LD	IY,BKPMSG
	CALL	PRTXT
	CALL    GETWRD 		; GET IT
	LD      (BREAK),DE      ; STORE IT IN TEMP
BKLP    CALL    STEP		; EXEC ONE INSTR
	LD      DE,(BREAK)
	LD      A,H		; CHECK IF AT BKPT
	CP      D
	JR      NZ,INTST-$
	LD      A,L
	CP      E
	JR	NZ,INTST-$
	CALL	STEP		; DO ONE MORE
	JR	DSPLY-$
INTST	CALL	KBST		; TEST FOR KBD INP
	JR	Z,BKLP-$	; CONTINUE IF NONE
	JR	QDSP-$
;
; RUN ONLY..NO DISPLAY OR BREAKPOINT
;
RUN     CALL    STEP		; DO A STEP
	CALL	KBST		; CHECK FOR KB INPUT
	JR	Z,RUN-$		; IF NONE JUST REPEAT
;
; STOP, DISPLAY, & RET TO CMND
;
QDSP	CALL	KBIN		; CLEAR UART
	JR	DSPLY-$		; DISP CPU & RET
; 
; DISPLAY & UPDATE CPU REGISTERS
;
RGSTR   PUSH    IX
	CALL    CRLF
	LD      IY,HEADR+42
	CALL    PRN6 		; PRINT RG NAME
	LD      DE,(NPC) 	; NEXT PC TO DE
	CALL    PRTWRD		; PRINT IT
	CALL    PROM 		; PROMPT FOR CHANGE
	CALL	GETWRD
	JR      Z,AREG-$ 	; SPACE = NO CHANGE
	LD	(NPC),DE	; PUT IN NEW VALUE
AREG    LD      IY,HEADR+12
	LD      B,5
NREG    CALL    CRLF 		; DO REST OF REGS
	CALL    PRN6 		; PRINT NAME
	LD      E,(IX+0)
	CALL    PRTBYT		; PRINT CONTENTS
	CALL    PROM		; PROMPT FOR CHANGE
	CALL	GETWRD
	JR      Z,NXTREG-$      ; SPACE = NO CHANGE
	LD      (IX+0),E
NXTREG  INC     IX		; POINT TO NEXT REG
	DJNZ    NREG-$ 		; DO AGAIN IF MORE
	POP     IX
	RET
;
; DISPLAY PC, INSTRUCTION, AND ALL REGISTERS
;
DSPLY	PUSH	IX		; SAVE POINTER
	PUSH	BC		; SAVE MNEMONIC CODE
	CALL	CRLF
	LD	IY,HEADR
	CALL	PRN6		; 'CPC'
	LD	DE,(CPC)
	CALL	PRTWRD		; VALUE
	CALL    PRN6		; 'INS'
	POP	BC
	PUSH	IY
	PUSH	BC
	LD	IY,MNMTBL	; DET MNEM FROM BC
	LD	A,0FCH
	AND	C
	SRL	A
	LD	E,A
	LD	D,0
	ADD	IY,DE
	LD	E,(IY+0)	; GET PACKED MNEM
	LD	D,(IY+1)
	SLA	E		; UNPACK IT
	RL	D
	LD	C,3		; & PRINT THREE CHRS
MNM2	XOR	A
	LD	B,5
MNM1	SLA	E
	RL	D
	RLA
	DJNZ	MNM1-$
	SET	6,A
	PUSH	BC
	CALL	PRNA
	POP	BC
	DEC	C
	JR	NZ,MNM2-$
	POP	BC		; DECODE ADDR MODE
	LD	A,B
	SLA	A
	SLA	A
	SLA	A
	LD	E,A
	LD	D,0
	LD	IY,AMDTBL
	ADD	IY,DE
	CALL	PRN8		; PRINT ADDR MODE
	POP	IY
	LD	B,5
DSP1	CALL	PRN6		; PRINT ALL REGS
	LD	E,(IX+0)
	CALL	PRTBYT
	INC	IX
	DJNZ	DSP1-$
	CALL	PRN6		; PRINT NEXT PC
	LD	DE,(NPC)
	CALL	PRTWRD
	POP	IX
	RET
;
PRN6	LD	E,6		; PRINT 6 CHARS PER IY
	JP	PRNLP
PRN8    LD      E,8		; PRINT 8 CHRS PER IY
	JP      PRNLP
;
; CODE FOR DECODING AND EXECUTING ONE INSTRUCTION
; ENTER WITH HL POINTING TO INSTR TO BE DECODED. EXITS
; WITH HL POINTING TO NEXT INSTR, B HOLDING ADDRESSING
; MODE CODE, C HOLDING MNEMONIC CODE
;
STEP    LD      HL,(NPC) 	; NEXT PC TO HL
	LD      (CPC),HL 	; BECOMES CURRENT PC
	LD      A,(HL) 		; OP CODE
	OR      A 		; ZERO?
	JP      Z,PBRK 		; IF SO, 'BRK'
	BIT     0,A		; TEST LSD FOR ODD/EVEN
	JP      NZ,MLTMOD	; ODD INSTRS MULTI MODE
	AND     0FH
	JR      NZ,FLGTST-$
	LD      A,(HL) 		; RESTORE OP CODE
	BIT     4,A		; MSD ODD/EVEN
	JP      NZ,PBRNCH	; IF ODD, BRANCH
	CP      20H
	JP      Z,PJSR		; PROCESS JSR
	CP      40H
	JP      Z,PRTI		; PROCESS RTI
	CP      60H
	JP      Z,PRTS		; PROCESS RTS
	JP      MLTMOD		; ELSE MULTI MODE
FLGTST  CP      8
	JR      NZ,IMP2-$
	LD      A,(HL)		; RESTORE
	BIT     4,A		; MSD ODD/EVEN
	JP      Z,PIMPL		; IF EVEN, MST BE IMPLD
	CP      98H		; MSD = 9?
	JP      Z,PTYA		; YES, PROC TYA SPECIAL
	JP      PFLGS		; ELSE PROCESS FLAG OPS
IMP2    CP      0AH
	JR      NZ,JMPTST-$     ; MUST BE JUMP
	LD      A,(HL)		; RESTORE
	AND     0F0H		; TESTS ON MSD
	BIT     4,A		; ODD/EVEN
	JP      NZ,PTSS		; PROSESS SP OPS SPECIAL
	CP      70H
	JP      C,MLTMOD 	; PROCESS ACCUM MODES
	JP      PIMPL   	; ELSE MORE IMPLIEDS
JMPTST  LD      A,(HL)		; RESTORE OP CODE
	CP      4CH
        JP      Z,PJABS		; PROCESS ABS JMP
	CP      6CH
        JP      Z,PJIND		; PROCESS INDIRECT JMP
	JP      MLTMOD
;
; INSTURCTION PROCESSORS BEGIN HERE.. ENTER WITH
; HL = PC, IX POINTING TO SIM CPU
;
; IF BRK VECTOR (IPOINT) = 0, RETURN TO CMND
;
PBRK	SET     4,(IX+1)	; SET BRK STATUS BIT
	LD	HL,(IPOINT)	; SEE IF RET TO CMND
	LD	A,H
	OR	L
	JR	NZ,BRK1-$
	POP	BC		; ADJUST SP
	LD	BC,429H		; RET TO CMND
	JP	DSPLY
BRK1	INC	HL		; NORMAL BREAK
        CALL    TSPY  		; SP TO IY
	LD      (IY+0),H	; 'PUSH' PC
        DEC     IY
	LD      (IY+0),L
        DEC     IY
	LD      A,(IX+1)	; 'PUSH' P
        LD      (IY+0),A
	DEC     IY
        CALL    TYSP  		; IY TO SP
	LD      HL,(IPOINT)	; GET INTERRUPT VECTOR
        LD      BC,429H		; CODE FOR # BYTES & MNEM
	JP      END1  		; AND FINISH
;
; PROCESS BRANCHES
;
PBRNCH	LD      B,0    		; FORM INDEX INTO MSKTBL
	LD      C,(HL)		; INSTR TO C
	LD	IY,MSKTBL
        SRL     C		; GET MSD
	SRL     C
        SRL     C
	SRL     C
        DEC     C
	ADD     IY,BC
        INC     HL     		; POINT TO OFFSET
	BIT     1,C		; MSD ODD/EVEN
	LD	A,(IX+1)	; P REG TO ACC
        LD      C,(IY+0)	; # CODE
	LD      B,(IY+1)	; FLAG MASK
        JR      NZ,BRSET-$	; ODD/EVEN DET SET/CLR
	AND     B     		; ISOLATE BIT FOR TEST
        JR      Z,TRUE-$
	JR      FALSE-$
BRSET   AND     B
	JR      NZ,TRUE-$
        JR      FALSE-$
TRUE    LD      D,0   		; CONDITION MET; BRANCH
	LD      E,(HL)		; OFFSET TO E
        BIT	7,E    		; CHECK SIGN OF OFFSET
	JR      Z,TRU1-$
        DEC     D      		; IF B7 IS SET, DO NEG
TRU1    ADD	 HL,DE 		; ADD OFFSET FOR NEW PC
FALSE   LD      B,0		; COND NOT MET; GO ON
	JP      END
;
; PROCESS JUMPS AND JSR...JMP 0-4 AND JSR 0-4 GO INTO Z80
; ROUTINES PER JUMP TABLE AT USR0. CONTROL THEN RETURNS
; TO SIMULATOR UPON Z80 'RET' (C9).. ALL OTHERS PROCESSED
; NORMALLY.
;
PJSR	LD	BC,273H		; JSR
	PUSH	BC
	CALL	SPCTST		; TEST FOR USER
	JR	NZ,PJS2-$
	CALL	INUSR		; GO TO USER SR
	POP	BC
	JR	EE0-$
PJS2	CALL	TSPY		; NORMAL JSR
	LD      (IY+0),H	; PUSH CURRENT PC
        DEC     IY
	LD      (IY+0),L
        DEC     IY
	CALL    TYSP
	JR	DOJ1-$
PJABS	LD      BC,26FH		; ABS JMP
        JR      DOJP-$
PJIND	LD	BC,0C6FH	; INDIRECT JMP
	CALL	SPCTST
	EX	DE,HL
	DEC	HL
DOJP	PUSH	BC
	CALL	SPCTST		; TEST FOR SPECIALS
	JR	NZ,DOJ1-$
	CALL	INUSR		; FOR SPECIALS
	CALL	PRET		; DO SR RETURN
	POP	BC
	JR	EE0-$		; GO TO PC+1
DOJ1	EX	DE,HL		; NEW PC
	POP	BC
	JR	EE1-$
;
; PROCESS SR AND INTERRUPT RETURNS
;
PRTS	CALL	PRET		; RTS...RESTORE PC
        LD      BC,4A9H
EE0	JP      END		; GO TO PC+1
PRTI	CALL	TSPY		; RTI
	INC	IY
	LD	A,(IY+0)	; RESTORE FLAGS
	LD	(IX+1),A
	CALL	PRET1		; RESTORE PC
	LD      BC,4A5H
EE1	JP      END1
PRET    CALL    TSPY  		; SP TO IY
PRET1	INC     IY    		; POINT TO LAST ENTRY
        LD      L,(IY+0)	; RESTORE PCL
	INC     IY
        LD      H,(IY+0)	; RESTORE PCH
	JP      TYSP  		; RESTORE NEW SP
;
; TEST FOR USER SUBROUTINE CALLS/JUMPS. IF TARGET
; ADDRESS < 0005 THEN RET WITH Z FLG SET, ELSE CLR
;
SPCTST	INC	HL		; TEST FOR USR SR
	LD	E,(HL)		; LO BYTE
	INC	HL		; TARGET TO DE
	LD	D,(HL)		; HI BYTE
	LD	A,0		; TARGET < 0005?
	OR	D
	RET	NZ
	LD	A,4
	CP	E
	RET	C
	XOR	A		; SET Z FLAG
	RET
;
; INDEX INTO USER SUBROUTINE TABLE
; PASS A, X, & Y TO/FROM USER ROUTINE AS A, B, & C.
;
INUSR	LD	D,0
	LD	A,E
	ADD	A,E
	ADD	A,E
	LD	E,A
	LD	IY,USR0
	LD	BC,USRET	; RETURN ON STACK
	PUSH	BC
	ADD	IY,DE
	LD	A,(IX+0)	; PASS A,X, & Y
	LD	B,(IX+2)
	LD	C,(IX+3)
	JP	(IY)		; AND GO
USRET	LD	(IX+0),A	; RETURN HERE
	LD	(IX+2),B	; RETURN PARAMETERS
	LD	(IX+3),C
	RET
	NOP			; PAD FOR PATCH
	NOP
	NOP
;
; PROCESS SP EXCHANGES
;
PTSS    CP      90H   		; WHICH ONE IS IT?
	JR      NZ,PTSX-$
PTXS    LD      A,(IX+2)	; MOVE DATA FROM X...
	LD      (IX+4),A	; TO SP
        LD      BC,4D9H
	JP      END
PTSX    LD      A,(IX+4)	; MOVE SP
	LD      (IX+2),A	; TO X REG
        LD      C,0D1H
	JP	COMPL		; AND MODIFY FLAGS
;
; PROCESS ALL REMAINING IMPLIED INSTRUCTIONS
;
PIMPL	LD	C,A		; OP CODE
	SRL     C     		; GET MSD
        SRL     C
	SRL     C
        SRL     C
	AND	0FH		; CHECK LSD
	CP	8
        LD      IY,IMPTBL	; INDEX INTO TABLE
	JP	Z,JPIB
	LD      IY,IMPTBL+8
	JP	JPIB
;
; IMPLIED INSTR PROCESSORS
;
PINX    INC     (IX+2)		; INX
	LD      C,65H
        JR      IDEFLG-$
PINY    INC     (IX+3)		; INY
	LD      C,69H
        JR      IDEFLG-$
PDEX    DEC     (IX+2)		; DEX
	LD      C,55H
        JR      IDEFLG-$
PDEY    DEC     (IX+3)		; DEY
	LD      C,59H
IDEFLG	RES	1,(IX+1)	; SET/RES Z FLG
	JR      NZ,SINTST-$	; PER Z80 FLAGS
        SET     1,(IX+1)
SINTST	RES	7,(IX+1)	; ALSO SIGN FLG
        JP      P,ENDIT
	SET     7,(IX+1)
        JP      ENDIT
PNOP	LD	BC,485H		; NOP
	JP	END
PPHA    CALL    TSPY  		; PHA
	LD      A,(IX+0)	; ACCUM
        LD      C,8DH
	JR      DOPUSH-$	; PUSH IT
PPHP    CALL    TSPY		; PHP
	LD      A,(IX+1)	; P REG
        LD      C,91H
DOPUSH	PUSH	BC
        LD      (IY+0),A	; PLACE ON STACK
	DEC     IY    		; BUMP SP DOWN
        CALL    TYSP  		; & REPLACE IT
	POP	BC
        JP      ENDIT
PPLA	CALL	DOPULL		; PLA
	LD      (IX+0),A	; DATA TO ACC
	CALL    SINS1 		; SET/RES S,Z FLGS
	CALL	TYSP		; RESTORE SP
        LD      BC,495H
	JP      END
PPLP	CALL	DOPULL		; PLP
	LD      (IX+1),A	; DATA TO P REG
        CALL    TYSP  		; RESTORE SP
	LD      BC,499H
        JP      END
DOPULL	CALL	TSPY		; GET SP
	INC     IY    		; BUMP SP
        LD      A,(IY+0)	; GET DATA
	RET
;
; PROCESS ACC/INDEX TRANSFERS
;
PTAX    LD      A,(IX+0)	; TAX
	LD      (IX+2),A
        LD      C,0C9H
	JR      COMPL-$
PTAY    LD      A,(IX+0)	; TAY
	LD      (IX+3),A
        LD      C,0CDH
	JR      COMPL-$
PTXA    LD      A,(IX+2)	; TXA
	LD      (IX+0),A
        LD      C,0D5H
	JR	COMPL-$
PTYA    LD      A,(IX+3)	; TYA
	LD      (IX+0),A
        LD      C,0DDH
COMPL   CALL    SINS1		; SET/RES S,Z FLGS
	JR	ENDIT-$
;
; PROCESS FLAG SET/RES INSTRUCTIONS
;
PFLGS	LD	IY,FLGTBL	; TABLE START
	LD	B,0
	CP	0B8H		; CLV SPECIAL
	JR	NZ,PFL1-$
	RES	5,A
PFL1	RRA			; CHECK MSD
	RRA
	RRA
	RRA
	AND	0EH		; MASK MSD + 1
	BIT	1,A		; TEST FOR SET/RES
	LD	C,A		; FORM TABLE INDEX
	ADD	IY,BC
	LD	C,(IY+0)	; GET MNEM CODE
	LD	A,(IY+1)	; GET MASK
	JR	NZ,PFL2-$
	CPL			; DO CLEARS
	AND	(IX+1)
	JR	PFL3-$
PFL2	OR	(IX+1)		; DO SETS
PFL3	LD	(IX+1),A	; AND STUFF IT
ENDIT	LD	B,4
	JP	END
;
; PROCESS ALL INSTRUCTIONS HAVING MULTIPLE ADDRESSING
;
MLTMOD  LD      BC,MLTEND	; PUT RETURN ON STACK
	PUSH    BC
        LD      A,(HL)		; GET INSTR TO A
	LD      C,A   		; AND TO C
        SRL     C     		; TEST EVEN/ODD
	PUSH	AF
        SRL     C     		; ROTATE MSD INTO LSD
	SRL     C
        SRL     C
	RES     0,C   		; MASK LSB
	POP	AF
        LD      IY,EVNTBL	; JUMP PER TABLES
	JP	NC,JPIB
	LD	IY,ODDTBL
	JP	JPIB
;
; MULTI-MODE INSTRUCTION PROCESSORS
;
PASL    CALL    MODBBB		; GET MODE,ADDR,&DATA
	SLA     A     		; ASL
        CALL    SINSET		; SET/RES S,Z,C FLGS
	CALL    PUTDAT		; RESTORE DATA
        LD      A,8
	RET
PBTRL   BIT     1,A   		; BIT OR ROL?
	JR      Z,PBIT-$
        CALL    MODBBB		; ROL
	CALL	CARSET		; SET UP C FLAG
PROL1   RLA           		; DO ROTATE
	CALL    SINSET
        CALL    PUTDAT
	LD      A,9CH
        RET
PBIT    RES     6,(IX+1)	; BIT
	CALL    MODBBX
        PUSH    BC
	LD      B,A   		; SAVE IT IN B
        LD      A,(IX+0)	; GET SIM ACC
	AND     B     		; AND IT
        BIT     6,A   		; CHECK V BIT
	JR      Z,PBIT1-$
        SET     6,(IX+1)	; SET V BIT IF REQD
PBIT1   CALL    SINS1 		; SET/RES S,Z FLGS
	POP     BC
        LD      A,18H
	RET
PLSR    CALL    MODBBB		; LSR
	SRL     A
        CALL    SINSET
	CALL    PUTDAT
        LD      A,80H
	RET
PROR    CALL    MODBBB		; ROR
	CALL	CARSET		; SET UP C FLG
PROR1   RRA           		; DO ROTATE
	CALL    SINSET
        CALL    PUTDAT
	LD      A,0A0H
        RET
PSTXY   BIT     1,A   		; WHICH ONE?
	JR      Z,PSY-$
        CALL    MODBBX		; STX
	LD      A,(IX+2)
	CALL    PUTDAT
        LD      A,0C0H
	RET
PSY     CALL    MODBBX		; STY
	LD      A,(IX+3)
	CALL    PUTDAT
        LD      A,0C4H
	RET
PLDXY   BIT     1,A   		; WHICH ONE?
	JR      Z,PLY-$
        CALL    MODDDD		; LDX
	LD      (IX+2),A
	CALL    SINS1
        LD      A,78H
	RET
PLY     CALL    MODDDD		; LDY
	LD      (IX+3),A
	CALL    SINS1
        LD      A,7CH
	RET
PDCY    BIT     1,A   		; WHICH ONE?
	JR      Z,PCPY-$
        CALL    MODBBX		; DEC
	DEC     A
        CALL    SINS1
	CALL    PUTDAT
        LD      A,50H
	RET
PICX    BIT     1,A   		; WHICH ONE?
	JR      Z,PCPX-$
        CALL    MODBBX		; INC
	INC     A
        CALL    SINS1
	CALL    PUTDAT
        LD      A,60H
	RET
PCPX    CALL    CXY   		; CPX
	CALL    SINSET
        LD      A,48H
	RET
PCPY    INC     IX
	CALL    CXY   		; CPY
        DEC     IX
	CALL    SINSET
        LD      A,4CH
	RET
CXY     CALL    MODCC
	PUSH    BC
        LD      B,A   		; MEM DAT INTO B
	LD      A,(IX+2)	; X (Y) INTO A
        SUB     B
	CCF           		; BORROW = 6502 /C
        POP     BC
	RET
PSBC    RES     6,(IX+1)	; SBC...CLR V FLG
	CALL    MODAAA
        PUSH    BC
	LD      B,A		; DATA TO B
        LD      A,(IX+0)	; ACC TO A
	CALL	CARSET		; SET UP C FLAG
	CCF			; AND COMPLEMENT IT
PSBC1   BIT     3,(IX+1)	; CHECK FOR DEC MODE
	JR      NZ,PSDEC-$
        SBC     A,B
	JR      PSBC2-$
PSDEC   SBC     A,B   		; DECIMAL MODE
	DAA
PSBC2   LD      (IX+0),A	; RESULT TO ACCUM
	CCF			; BORROW = 6502 /C
	CALL	SINSET
	AND	0C0H		; TEST XOR OF B6 & B7
	JR	Z,SBC3-$
	CP	0C0H
	JR	Z,SBC3-$
	SET     6,(IX+1)	; SET V FLAG IF XOR = 1
SBC3	POP     BC
        LD      A,0ACH
	RET
PORA    CALL    MODAAA		; ORA
	PUSH    BC
        LD      B,A   		; DATA TO B
	LD      A,(IX+0)	; ACC TO A
        OR      B
	LD      (IX+0),A	; RESULT TO ACC
        CALL    SINS1
	POP     BC
        LD      A,88H
	RET
PAND    CALL    MODAAA		; AND
	PUSH    BC
        LD      B,A   		; DATA TO B
	LD      A,(IX+0)	; ACC TO A
        AND     B
	LD      (IX+0),A	; RESULT TO ACC
        CALL    SINS1
	POP     BC
        LD      A,4
	RET
PEOR    CALL    MODAAA		; EOR
	PUSH    BC
        LD      B,A		; DATA TO B
	LD      A,(IX+0)	; ACC TO A
        XOR     B
	LD      (IX+0),A	; RESULT TO ACC
        CALL    SINS1
	POP     BC
        LD      A,5CH
	RET
PADC    RES     6,(IX+1)	; ADC: CLEAR V FLAG
	CALL    MODAAA
        PUSH    BC
	LD      B,A		; DATA TO B
        LD      A,(IX+0)	; ACC TO A
	CALL	CARSET		; SET UP C FLG
PADC1   BIT     3,(IX+1)	; CHECK FOR DEC MODE
	JR      NZ,PADEC-$
        ADC     A,B   		; BINARY MODE
	JR      PADC2-$
PADEC   ADC     A,B   		; DECIMAL MODE
	DAA
PADC2   LD      (IX+0),A	; RESULT TO ACC
	CALL	SINSET
	AND	0C0H		; CHECK XOR OF B6 & B7
	JR	Z,PADC3-$
	CP	0C0H
	JR	Z,PADC3-$
	SET     6,(IX+1)	; SET V FLG IF XOR = 1
PADC3   POP     BC
	LD      A,0
        RET
PSTA    CALL    MODAAA		; STA
	LD      A,(IX+0)	; ACC TO MEM
        CALL    PUTDAT
	LD      A,0BCH
        RET
PLDA    CALL    MODAAA		; LDA
	LD      (IX+0),A	; MEM TO ACC
        CALL    SINS1
	LD      A,74H
        RET
PCMP    CALL    MODAAA		; CMP
	PUSH    BC
        LD      B,A   		; DATA TO B
	LD      A,(IX+0)	; ACC TO A
        SUB     B
	CCF           		; BORROW = 6502 /C
        CALL    SINSET
	POP     BC
        LD      A,44H
	RET
;
; END OF ALL MULTI MODE PROCESSORS
;
MLTEND  ADD     A,C		; FORM MNEM CODE IN C
	LD      C,A
END     INC     HL		; POINT TO NXT INSTR
END1    LD      (NPC),HL
	RET			; BACK TO CMND
;
; VARIOUS SUBROUTINES FOR TRANSLATOR
;
; SET Z80 C FLAG TO MATCH 6502 C FLG
;
CARSET	SCF
	BIT	0,(IX+1)
	RET	NZ
	CCF
	RET
;
; SET SIMULATOR S,Z,C FLAGS PER Z80 RESULTS
;
SINSET  RES     0,(IX+1)	; RESET C FLAG
	JR      NC,SINS1-$
        SET     0,(IX+1)	; SET C PER Z80 C
SINS1   RES     1,(IX+1)	; CLEAR Z FLAG
	OR      A     		; SEE IF ACC = 0
        JR      NZ,SINS2-$
	SET     1,(IX+1)	; SET Z FLG
SINS2   RES     7,(IX+1)	; CLEAR SIGN FLAG
	BIT     7,A   		; CHECK SIGN OF ACC
        RET     Z
	SET     7,(IX+1)	; SET S IF NECESSARY
        RET
;
; TRANSFER SIMULATOR SP TO/FROM IY
;
TSPY	LD      B,1   		; XFER SP TO IY
        LD      C,(IX+4)
	PUSH	BC
	POP	IY
        RET
TYSP	PUSH	IY		; XFER IY TO SP
	POP	BC
	LD      (IX+4),C
        RET
;
; ADDRESS MODE DECODERS...RETURN WITH DATA TO BE MODIFIED
; IN A, ADDRESS MODE CODE IN B, # BYTES IN C, ADDRESS OF
; DATA IN DE
;
MODAAA  LD      IY,AAATBL	; GROUP 1
	JR      MOD1-$
MODBBB  LD      IY,BBBTBL	; GROUP 2
	JR      MOD1-$
MODDDD  LD      IY,DDDTBL	; GROUP 3
        CP      0B6H  		; LDX ZPG,Y SPECIAL
	JR      NZ,DDD1-$
        LD      A,10H
DDD1    CP      0BEH  		; LDX ABS,Y SPECIAL
	JR      NZ,MOD1-$
        LD      A,18H
	JR      MOD1-$
MODBBX  LD      IY,BBXTBL	; GROUP 4 & 6
        CP      96H   		; STX ZPG,Y SPECIAL
	JR      Z,BBX-$
	RRA			; EXTRA SHIFT
	AND	0CH		; EXTRA MASK
	JR	MOD1-$
BBX	LD	A,10H		; SPECIAL
	JR	MOD1-$
MODCC   LD      IY,CCTBL	; GROUP 5
MOD1	RRA           		; ROTATE MODE INTO LSD
        AND     0EH   		; MASK THE REST
        LD      B,0   		; FORM OFFSET IN BC
	LD      C,A
        ADD     IY,BC 		; ADD TO TABLE START
	LD      C,(IY+0)	; MODE OFFSET
        LD      B,(IY+1)	; # CODE
	PUSH    BC    		; SAVE FOR LATER
GETDAT  LD      IY,GETTBL	; JUMP TABLE
	JP	JPIB
PABY    INC     HL    		; ABS,Y
	LD      A,(HL)		; 2ND BYTE INSTR
        ADD     A,(IX+3)	; PLUS Y INDEX
	LD      E,A   		; TO E
        INC     HL
	LD      A,(HL)		; 3RD BYTE INSTR
        ADC     A,0   		; PLUS CARRY
	LD      D,A   		; TO D
        JR      EXIT-$
PIMM    INC     HL    		; IMMEDIATE
	LD      A,(HL)		; DATA TO ACC
        JR      EX1-$
PACX    LD      A,(IX+0)	; ACCUM
	PUSH    IX
        POP     DE
	JR      EX1-$
PZPG    INC     HL    		; ZPG
	LD      E,(HL)		; ADDRESS TO DE
        LD      D,0
	JR      EXIT-$
PAB     INC     HL    		; ABSOLUTE
	LD      E,(HL)		; ADDRESS TO DE
        INC     HL
	LD      D,(HL)
        JR      EXIT-$
PZX     LD      A,(IX+2)	; ZPG,X...GET X INDEX
	JR      PZ1-$
PZY     LD      A,(IX+3)	; ZPG,Y...GET Y INDEX
PZ1     INC     HL
	ADD     A,(HL)		; ADD BASE ADDRESS
        LD      E,A   		; PUT IN E
	LD      D,0   		; ZERO PAGE, NO WRAP
        JR      EXIT-$
PZIX    INC     HL    		; (ZPG,X)
	LD      A,(HL)		; 2ND BYTE INSTR
        ADD     A,(IX+2)	; ADD X INDEX
	LD      E,A   		; TO FORM BASE ADDRESS...
        LD      D,0   		; IN ZERO PG, NO WRAP
	LD      IY,0
        ADD     IY,DE 		; TRANSFER TO IY
	LD      E,(IY+0)	; EFF ADDR TO DE
        LD      D,(IY+1)
	JR      EXIT-$
PZIY    INC     HL    		; (ZPG),Y
	LD      E,(HL)		; BASE ADDRESS
        LD      D,0   		; IN ZERO PAGE
	LD      IY,0
        ADD     IY,DE 		; TRANSFER TO IY
	LD      A,(IY+0)	; EFF ADDRESS...
        ADD     A,(IX+3)	; PLUS Y INDEX...
	LD      E,A   		; TO DE
        LD      A,(IY+1)
	ADC     A,0
        LD      D,A
	JR      EXIT-$
PABX    INC     HL    		; ABS,X
	LD      A,(HL)		; 2ND BYTE INSTR
        ADD     A,(IX+2)	; PLUS X INDEX
	LD      E,A   		; TO E
        INC     HL    		; 3RD BYTE INSTR
	LD      A,(HL)
        ADC     A,0   		; PLUS CARRY
	LD      D,A   		; TO E
EXIT    LD      A,(DE)		; DATA TO ACC
EX1     POP     BC    		; RESTORE # CODE
	PUSH    AF    		; SAVE DATA
        LD      A,3
	AND     B     		; # BYTES...
        LD      C,A   		; TO C
	SRL     B
        SRL     B     		; B=ADDR MODE
	POP     AF    		; RESTORE DATA
        RET
;
; STORE DATA TO ADDRESS FROM GETDAT
;
PUTDAT  LD      (DE),A
	RET
;
; INDEX INTO JUMP TABLES...ENTER WITH TABLE START
; ADDRESS IN IY AND OFFSET IN C. CALCULATES TABLE
; POSITION AND JUMPS TO RESULT
;
JPIB	LD	B,0		; INDIRECT JUMP PER TABLE
	ADD	IY,BC		; TABLE ADDRESS TO IY
	LD	C,(IY+0)	; TABLE ENTRY TO BC
	LD	B,(IY+1)
	PUSH	BC
	POP	IY		; ENTRY TO IY
	JP	(IY)		; AND GO TO IT
;
; ELEMENTARY MONITOR FUNCTIONS TO EXAMINE A BLOCK OF
; MEMORY LOCATIONS (E) AND TO CHECK AND UPDATE
; INDIVIDUAL LOCATIONS (M)
;
EXAM	LD	DE,GETADR	; EXAM BLOCK OF MEM
	CALL	PRTDE
	CALL	GETWRD		; GET START ADDR
	PUSH	DE
	CALL	LINF
	LD	DE,GETN
	CALL	PRTDE
	CALL	GETWRD		; GET # BYTES
	PUSH	DE
	POP	BC
	LD	E,4		; CHANGE TO # LINES (/16)
	XOR	A
BYTLN	SRL	B
	RR	C
	JR	NC,XXX-$
	INC	A
XXX	DEC	E
	JR	NZ,BYTLN-$
	OR	A		; SEE IF PARTIAL LINE
	JR	Z,YYY-$
	INC	BC
YYY	POP	HL		; HL = START, BC = COUNT
	DEC	BC		; ONE LESS LINE
EXLP	PUSH	BC		; LOOP FOR ONE LINE
	CALL	CRLF
	CALL	LADR		; PRINT ADDRESS AT START
	CALL	TWO		; INSERT TWO SPACES
	PUSH	HL		; SAVE ADDRESS FOR ALPHA
	LD	E,16		; 16 ENTRIES PER LINE
LNLP	LD	A,(HL)		; GET BYTE FROM MEMORY
	CALL	PACC		; PRINT IT HEX
	CALL	ONE		; SPACE
	INC	HL		; POINT TO NEXT BYTE
	DEC	E		; DONE WITH HEX?
	JR	NZ,LNLP-$	; NO, DO NEXT BYTE
	CALL	TWO		; YES, SET UP FOR ALPHA
	POP	HL		; SAME STARTING ADDRESS
	LD	E,16
ASCII	LD	A,(HL)		; GET BYTE
	CP	20H		; IS IT PRINTABLE?
	JR	C,DOT-$
	CP	80H
	JR	C,ASOK-$
DOT	LD	A,'.'		; NO, PRINT A DOT
ASOK	CALL	PRNA
	INC	HL		; BUMP POINTER
	DEC	E		; DONE WITH LINE?
	JR	NZ,ASCII-$
	POP	BC
	LD	A,B		; SEE IF ALL DONE
	OR	C
	RET	Z		; YES, RET TO CMND
	DEC	BC
	JR	EXLP-$		; ELSE DO ANOTHER LINE
;
; SUBSTITUTE MEMORY...ENTER BY 'M'
;
SUBM	LD	DE,GETADR	; ASK FOR ADDRESS
	CALL	PRTDE
	CALL	GETWRD		; GET IT
	EX	DE,HL		; MOVE IT TO HL
SULP	CALL	CRLF
	CALL	LADR		; PRINT THE ADDRESS
	CALL	TWO
	LD	A,(HL)
	CALL	PACC		; PRINT THE CONTENTS
	CALL	TWO
JLP	CALL	GETCHR		; GET INPUT
	CP	2EH		; EXIT ON "."
	RET	Z
	CP	20H
	JR	Z,FWD-$		; SKIP AHEAD ON "SPACE"
	CALL	CONV		; CONV HEX IF POSSIBLE
	JR	Z,JLP-$		; NOT A HEX NUMBER
	PUSH	HL		; SAVE ADDRESS AGAIN
	LD	HL,0		; CLEAR FOR ROTATE
LLP	CALL	ROBYT		; ROTATE NYBBLE INTO HL
KLP	CALL	GETCHR		; GET ANOTHER CHARACTER
	CP	0DH
	JR	Z,PUTIN-$	; IF "CR" STUFF IT
	CALL	CONV		; CONV BINARY
	JR	Z,KLP-$		; NOT A HEX NUMBER
	JR	LLP-$		; CONTINUE
PUTIN	PUSH	HL		; DATA TO BC
	POP	BC
     	POP	HL		; RETRIEVE ADDRESS
	LD	(HL),C		; STUFF THE DATA
FWD	INC	HL		; BUMP POINTER
	JR	SULP-$		; ...AND CONTINUE
LADR	EX	DE,HL		; PRINT WORD IN HL
	CALL	PRTWRD
	EX	DE,HL
	RET
PACC	PUSH	DE		; PRINT BYTE IN A
	LD	E,A
	CALL	PRTBYT
	POP	DE
	RET
TWO	CALL	ONE		; PRINT 2 SPACES
ONE	PUSH	BC		; PRINT SPACE
	LD	C,' '
	CALL	PRNC
	POP	BC
	RET
;
; ELEMENTARY DOS BEGINS HERE. FILES ARE MAINTAINED ON
; DRIVE B ONLY AND ARE NOT CP/M COMPATIBLE. FUNCTIONS
; ARE DIRECTORY LIST (D), SAVE (S), LOAD (L), KILL (K)
; AND INITIALIZE (I).
; FILE NAMES CONSIST OF A PRIMARY FILE NAME OF UP TO
; SIX CHARS AND AN OPTIONAL FILE TYPE OF UP TO THREE.
;
; LIST DIRECTORY
;
PDIR	CALL	DIR1		; SET UP FOR DIR SCH
PAGLP	CALL	NEWPG		; NEXT DIR PG TO BUFF
	LD	B,8		; 8 ENTRIES/PAGE
PRPAG	LD	A,(IX+0)	; STATUS BYTE
	DEC	A
	RET	Z		; QUIT IF DONE
	DEC	A
	JR	NZ,NEXT-$
	CALL	CRLF
PRLIN	PUSH	BC		; PRINT NAME FROM DIR
	PUSH	IX
	LD	B,10
PLNLP	LD	C,(IX+1)
	CALL	PRNC
	INC	IX
	DJNZ	PLNLP-$
	POP	IX
	CALL	SPAC
	LD	E,(IX+11)	; PRINT ADDRESS
	LD	D,(IX+12)
	CALL	PRTWRD
	CALL	SPAC
	LD	E,(IX+15)	; PRINT # RECORDS
	CALL	PRTBYT
	POP	BC
NEXT	LD	DE,10H
	ADD	IX,DE		; POINT TO NXT ENTRY
	DJNZ	PRPAG-$		; AND REPEAT
	JR	PAGLP-$
;
; LOAD PGM FROM DRIVE B AND RUN FROM START ADDRESS
;
LDGO	CALL	LOAD		; GET PGM
	LD	IX,VREG		; FOR SIMULATOR
	JP	RUN
;
; SEARCH FOR AND LOAD A FILE AT ADDR PER DIRECTORY
;
LOAD	CALL	ANAME		; LOAD A FILE
	CALL	NAMSCH		; TRY TO MATCH NAME
	JP	Z,NTFND
	LD	L,(IY-5)	; SAVE START ADDR
	LD	H,(IY-4)
	LD	(NPC),HL
LOADLP	CALL	SETDAT		; SET UP FOR LOAD
	CALL	RDONE		; AND READ N SECTORS
	CALL	INCDAT
	JR	NZ,LOADLP-$
	RET
;
; SAVE A FILE AND ADD IT TO DIRECTORY
;
SAVE	CALL	ANAME		; SAVE # SECTORS
	CALL	NAMSCH		; SEE IF HAVE ALREADY
	JR	Z,SAV1-$
	CALL	LINF
	LD	DE,HAVMSG	; IF SO, INFORM & QUIT
	CALL	PRTDE
	RET
SAV1	LD	IY,TEMPS
	LD	A,2		; NEW ACTIVE FILE
	LD	(IY+0),A
	CALL	LINF
	LD	DE,GETADR	; GET RUN ADDR
	CALL	PRTDE
	CALL	GETWRD
	LD	(IY+11),E
	LD	(IY+12),D
	CALL	LINF
	LD	DE,GETN		; GET # BYTES
	CALL	PRTDE
	CALL	GETWRD
	XOR	A		; CONVERT TO SECTORS
	LD	B,7		; DIV BY 128
SAVX	SRL	D
	RR	E
	JR	NC,SAVY-$
	INC	A
SAVY	DJNZ	SAVX-$
	OR	A		; FRACTIONAL SCTR?
	JR	Z,SAVZ-$
	INC	E		; THEN ADD ONE
SAVZ	LD	(IY+15),E	; SAVE IT
	CALL	DIR1		; SET UP FOR DIR SCH
SAV2	CALL	NEWPG		; SEARCH FOR NAME
	LD	B,8
SAV3	LD	A,(IX+0)	; STAT BYTE
	DEC	A
	JR	Z,SAVNEW-$	; NEW FILE
	SUB	2		; DEAD FILE?
	JR	NZ,SAV4-$
	LD	A,(IY+15)	; WILL IT FIT?
	DEC	A
	CP	(IX+15)
	JR	C,SAVOLD-$
SAV4	LD	DE,10H		; CHECK NXT ONE
	ADD	IX,DE
	LD	D,(IX-3)	; OLD TRACK
	LD	E,(IX-2)	; OLD SECTOR
	LD	C,(IX-1)	; OLD #
	DJNZ	SAV3-$
	JR	SAV2-$
SAVNEW	LD	A,26		; NEW ENTRY
	INC	C
NEWLP	INC	E
	CP	E		; >26?
	JR	NC,NEW1-$
	INC	D		; IF SO, NXT TRK
	LD	E,1
NEW1	DEC	C
	JR	NZ,NEWLP-$
	JR	UPDIR-$
SAVOLD	LD	D,(IX+13)
	LD	E,(IX+14)
UPDIR	LD	(IY+13),D	; PUT NEW TRK & SCTR
	LD	(IY+14),E
	CALL	PUTDIR		; UPDATE DIR
SAVER	CALL	SETDAT		; SET UP FOR SAVE
	CALL	WRONE		; & WRITE # SECTORS
	CALL	INCDAT
	JR	NZ,SAVER-$
	RET
;
; KILL A FILE (SET INACTIVE STATUS IN DIRECTORY)
;
KILL	CALL	ANAME		; GET NAME
	CALL	NAMSCH		; FIND IT
	JP	Z,NTFND
	LD	IY,TEMPS
	LD	A,3		; MAKE STAT = 03
	LD	(IY+0),3
	JR	PUTDIR-$	; AND UPDATE DIRECTORY
;
; INITIALIZE DISK (WRITES BLANK DIRECTORY)
;
INIT	LD	DE,INIMSG	; INITIALIZE DISK
	CALL	PRTDE
	CALL	GETCHR		; ASK YES OR NO
	CP	'Y'
	RET	NZ
	CALL	HOMB
	LD	IX,BUFFR	; FILL BUFF W/PATTERN
	LD	IY,INIMSK	; STORED AT INIMSK
	PUSH	IX
	LD	C,8
INLP1	PUSH	IY
	LD	B,10H
INLP2	LD	A,(IY+0)
	LD	(IX+0),A
	INC	IX
	INC	IY
	DJNZ	INLP2-$
	POP	IY
	DEC	C
	JR	NZ,INLP1-$
	POP	IX
	LD	A,3		; MAKE 1ST ONE DEAD
	LD	(IX+0),A
	LD	BC,BUFFR
	CALL	BUFS
	LD	C,0
	CALL	TRKS
	INC	C
	CALL	SECS
	CALL	WRONE		; 1ST DIR PAGE
	LD	A,1		; RESTORE PATTERN
	LD	(IX+0),A
	LD	BC,1902H
WRLP	PUSH	BC		; WRITE REST OF TRK 0
	CALL	SECS
	CALL	WRONE
	POP	BC
	INC	C
	DJNZ	WRLP-$
	RET
;
; OVERWRITE CURRENT DIRECTORY PAGE
;
PUTDIR	LD	B,10H		; UPDATE DIR
UPLP	LD	A,(IY+0)
	LD	(IX+0),A
	INC	IX
	INC	IY
	DJNZ	UPLP-$
	CALL	WRONE		; REWRITE DIR PAGE
	RET
;
; SEARCH FOR FILE NAME IN DIRECTORY.. RETURN WITH Z FLG
; SET IF NOT FOUND, Z CLEAR AND BUFFER FILLED IF FOUND
;
NAMSCH	CALL	DIR1		; SET UP FOR DIR SCH
LDLP	CALL	NEWPG		; READ PAGE OF NDX
	LD	B,8
LDLP1	LD	A,(IX+0)	; CHECK STAT
	DEC	A
	JR	NZ,LDLP2-$
	RET
LDLP2	DEC	A
	PUSH	IX
	PUSH	IY
	JR	NZ,LDNXT-$	; INACTIVE?
	LD	C,10		; ELSE COMP NAME
CMPLP	LD	A,(IY+1)
	CP	(IX+1)
	JR	NZ,LDNXT-$
	INC	IX
	INC	IY
	DEC	C
	JR	NZ,CMPLP-$
	JR	CMPOK-$		; SAME NAME
LDNXT	POP	IY		; TRY NEXT ONE
	POP	IX
	LD	DE,10H
	ADD	IX,DE
	DJNZ	LDLP1-$
	JR	LDLP-$		; NEXT PAGE
CMPOK	POP	IY		; NAME MATCHES
	POP	IX
	LD	B,10H		; XFER DIR NTRY TO BUFF
FILLP	LD	A,(IX+0)
	LD	(IY+0),A
	INC	IX
	INC	IY
	DJNZ	FILLP-$
	LD	DE,-10H
	ADD	IX,DE
	XOR	A
	INC	A		; EXIT A = 1
	RET
NEWPG	EXX			; GET NXT DIR PAGE
	LD	IX,BUFFR
	INC	(IY+14)		; NXT SCTR
	LD	C,(IY+14)
	CALL	SECS
	CALL	RDONE		; READ IT IN
	EXX
	RET
NTFND	CALL	LINF		; NOT FOUND
	LD	DE,NFMSG
	CALL	PRTDE
	LD	SP,SYSTK-2	; RET TO CMND
	RET
;
; FILL IN DISK DATA. USES SR CALLS IN CBIOS
;
SETDAT	LD	IY,TEMPS	; SET UP FOR DSK DATA
	LD	C,(IY+11)
	LD	B,(IY+12)
	CALL	BUFS		; XFER ADDR
	LD	C,(IY+13)
	CALL	TRKS		; TRACK
	LD	C,(IY+14)
	JP	SECS		; SECTOR
;
; BUMP SECTOR/TRACK AND XFER ADDRESS FOR MULTI
; SECTOR READ OR WRITE
;
INCDAT	LD	A,(IY+11)	; BUMP DSK DATA
	ADD	A,80H		; BUMP XFER ADDR
	LD	(IY+11),A
	JR	NC,INC1-$
	INC	(IY+12)
INC1	LD	A,(IY+14)
	INC	A		; BUMP SECTOR
	CP	27
	JR	C,INC2-$
	LD	A,1
	INC	(IY+13)		; AND TRK IF NEEDED
INC2	LD	(IY+14),A
	LD	A,(IY+13)	; CHECK FOR VALID TRACK
	CP	77
	JR	C,INC3-$
	LD	DE,DERMSG	; ERROR
	CALL	PRTXT
	POP	BC		; RET TO CMND
	RET
INC3	DEC	(IY+15)
	RET
;
; GET FILE NAME TO BUFFER
;
ANAME	LD	IY,TEMPS
	PUSH	IY
	LD	B,10
	LD	A,' '
MPTY	LD	(IY+1),A	; CLEAR INPUT BUFFER
	INC	IY
	DJNZ	MPTY-$
	LD	DE,NAMSG	; PROMPT FOR NAME
	CALL	PRTDE
	POP	IY
	PUSH	IY
NAMLP	CALL	GETCHR
	CP	0DH		; END?
	JR	Z,NAMIN-$
	CP	'.'		; DELIMITER?
	JR	Z,FTYP-$
	LD	(IY+1),A	; PUT IT IN BUFFER
	INC	IY
	JR	NAMLP-$
FTYP	POP	IY
	PUSH	IY
	LD	(IY+7),A
	INC	IY
TYPLP	CALL	GETCHR
	CP	0DH
	JR	Z,NAMIN-$
	LD	(IY+7),A
	INC	IY
	JR	TYPLP-$
NAMIN	POP	IY
	RET
;
; SET UP FOR DIRECTORY SEARCH
;
DIR1	LD	IY,TEMPS	; SET UP FOR DIR SCH
	LD	BC,BUFFR
	CALL	BUFS
	LD	C,0		; TRACK 0
	LD	(IY+13),C
	LD	(IY+14),C
	JP	TRKS
;
; VARIOUS ROUTINES USED BY TRANSLATOR, MONITOR, AND DOS
;
CRLF    LD      C,0DH		; PRINT CRLF
	CALL    PRNC
LINF    LD      C,0AH
	JP      PRNC
PROM    LD      C,' '		; PRINT ' >'
	CALL    PRNC
        LD      C,'>'
	JP      PRNC
;
; GET HEX DATA IN DE. ROTATE CONTINUOUSLY UNTIL A
; 'CR' IS INPUT. LSB IN E. SET Z FLG AND RET ON 'SPACE'
;
GETWRD  CALL    GETCHR		; GET BINARY DATA
	CP      ' '   		; RET Z IF SACE
        RET     Z
	EX      DE,HL
        LD      HL,0  		; CLEAR HODING REG
	CALL	CONV		; CHANGE TO HEX
	JR	Z,GETWRD-$	; INVALID CHAR
	CALL	ROBYT		; ROTATE INTO HL
WRDLP   CALL    GETCHR		; GET NEXT CHAR
	CP      0DH   		; TERMINATOR
	JR	Z,WRDON-$
	CALL	CONV
	JR	Z,WRDLP-$
	CALL	ROBYT
	JR	WRDLP-$
WRDON	OR      A     		; CLEAR Z FLAG
        EX      DE,HL 		; DATA INTO DE
	RET
;
; CONVERT ASCII DATA IN A TO HEX. SET Z FLG IF INVALID
;
CONV    CP      '0'   		; CONVERT TO BINARY
	JR      C,BAD-$
        CP      3AH
	JR      C,GOOD-$
        CP      41H
	JR      C,BAD-$
        CP      47H
	JR      C,GOOD-$
BAD     LD      C,'?'
	CALL    PRNC		; NOTIFY BAD INPUT
	XOR	A		; SET Z FLAG
	RET
GOOD    SUB     30H
	CP      10
	JR      C,GOOD1-$
	SUB     7
GOOD1	CP	0FFH		; CLEAR Z FLAG
	RET
;
; ROTATE BYTE IN A INTO HL VIA L
;
ROBYT	ADD	HL,HL		; ROTATE A INTO HL
	ADD     HL,HL		; ROTATE HL 4 BITS LEFT
	ADD     HL,HL
	ADD     HL,HL
	OR      L     		; PUT NEW DIGIT INTO L
	LD      L,A
	RET
;
; PRINT FOUR DIGIT VALUE IN DE
;
PRTWRD  LD      A,D
	CALL    PRBIN
PRTBYT  LD      A,E   		; PRINT VALUE IN E
PRBIN   PUSH    AF
	RRC     A
	RRC     A
	RRC     A
	RRC     A
	CALL    PRB1
	POP     AF
PRB1    AND     0FH
	ADD     A,90H
	DAA
	ADC     A,40H
	DAA
	JR      PRNA-$
;
; PRINT STRING POINTED TO BY DE. USES PRTXT
;
PRTDE	PUSH	IY		; PRNT PER DE
	PUSH	DE
	POP	IY
	CALL	PRTXT
	POP	IY
	RET
;
; PRINT ASCII STRING POINTED TO BY IY. CHECK FOR
; SPECIALS: '1' PRINTS AS BYTE POINTED TO BY HL, '2'
; PRINTS (HL+1), '!' DOES NOT PRINT, '^' TERMINATES.
;
PRTXT   LD      E,0   		; PRNT UP TO 255 CHRSY
PRNLP   LD      A,(IY+0)
	CP      '^'		; TERMINATOR?
	RET     Z
	CP      '!'		; NO PRINT?
	JR      Z,DONXT+1-$
	PUSH    DE
	LD      HL,(CPC)
	INC     HL
	CP      '2'		; PRINT (HL+1)?
	JR      NZ,PRN1-$
	INC     HL
	LD      E,(HL)
	CALL    PRTBYT
	JR      DONXT-$
PRN1    CP      '1'		; PRINT (HL)?
	JR      NZ,DOALPH-$
	LD      E,(HL)
	CALL    PRTBYT
	JR      DONXT-$
DOALPH  LD      C,A		; ALL OTHER CHARACTERS
	CALL    PRNC
DONXT   POP     DE
	INC     IY
	DEC     E
	JR      NZ,PRNLP-$
	RET
;
SPAC    PUSH    BC    		; PRINT 6 SPACES
	LD      B,6
	LD      C,' '
SPLP    CALL    PRNC
	DJNZ    SPLP-$
	POP     BC
	RET
;
; CONSOLE I/O
;
GETCHR  CALL    KBIN 		; GET CHAR & TEST
	CP	3		; ^C....
	JP	Z,CPWRM		; CPM WARM START
	CP	18H		; ^X (CAN)...
	JR	NZ,PRNA-$
	LD	SP,SYSTK-2	; FOR RET TO CMND
	LD	A,'#'
PRNA    LD      C,A		; PRINT CHAR IN A
	PUSH	AF
	CALL	PRNC
	POP	AF
	RET
;
; JUMPS TO EXTERNAL I/O...MODIFY AS NEEDED
;
KBIN	JP	CONIN		; GET SINGLE CHAR IN A
KBST	JP	CONST		; TEST INPUT STATUS
PRNC    JP      CONOUT		; PRINT CHAR IN C
HOMB	JP	HOME		; DRIVE HOME
DRVS	JP	SETDRV		; SET DRIVE #
SECS	JP	SETSEC		; SET SECTOR #
TRKS	JP	SETTRK		; SET TRK #
BUFS	JP	SETBUF		; SET XFER ADDRESS
RDONE	JP	READ		; READ A SECTOR
WRONE	JP	WRITE		; WRITE A SECTOR
;
; JUMP TABLE FOR LINKS TO Z80 ROUTINES...FILL IN AS REQD
; FIRST TWO INITIALIZED TO CONSOLE I/O VIA ACC
;
USR0	JP	KBIN		; 6502 USER ROUTINES
USR1	JP	PRNA
USR2	DEFB	0C9H,0,0
USR3	DEFB	0C9H,0,0
USR4	DEFB	0C9H,0,0
;
; 6502 BREAK VECTOR...INIT TO GO TO COMMAND LEVEL
;
IPOINT	DEFW	0
;
; TEMPORARIES FOR TRANSLATOR
;
NSTEPS  DEFB    1     		; # STEPS TO EXECUTE
NBYTES  DEFB    0     		; # BYTES IN INSTR
DLYCON	DEFW	0A00H		; TIME DELAY FOR # STEP
BREAK   DEFW    0     		; BREAKPOINT ADDRESS
;
; SIMULATED 6502 CPU REGISTERS...INIT TO THESE VALUES
;
VREG    DEFB    0     		; ACCUMULATOR
	DEFB    0     		; STATUS (P) REG
	DEFB    0     		; X INDEX REG
	DEFB    0     		; Y INDEX REG
	DEFB    0FFH  		; STACK POINTER
CPC     DEFW    200H     	; PROGRAM COUNTER
NPC     DEFW    200H   		; LOCATION OF NXT INSTR
;
; VARIOUS MESSAGES FOR SYSTEM
;
INTRO   DEFM    '***** XENTRIX ZX/65 *****^'
HEADR   DEFM    ' CPC.. INS.. A.... P....'
	DEFM    ' X.... Y.... SP... NPC..'
NFMSG	DEFM	'FILE NOT FOUND^'
HAVMSG	DEFM	'FILE EXISTS^'
DERMSG	DEFM	'BAD TRACK/SECTOR #^'
GETADR	DEFM	'  ENTER START ADDRESS: ^'
GETN	DEFM	'  ENTER NO. BYTES: ^'
NAMSG	DEFM	'  ENTER FILNAM.TYP: ^'
MLTMSG	DEFM	'  ENTER # STEPS: ^'
BKPMSG	DEFM	'  ENTER BRKP ADDR: ^'
INIMSG	DEFM	'  INITIALIZE? (Y/N) ^'
;
; DOS BUFFERS AND DATA
;
TEMPS	DEFS	10H		; DISK ENTRY BUFFER
BUFFR	DEFS	80H		; DIRECTORY PAGE BUFFER
INIMSK	DEFB	1,20H,20H,20H,20H,20H,20H,20H
	DEFB	20H,20H,20H,20H,20H,1,0,0
;
; DATA TABLES FOR TRANSLATOR BEGIN HERE
;
; ADDRESSING MODE TABLES
;
AAATBL  DEFW    1A0CH 		; (ZPG,X)
	DEFW    0E04H 		; ZPG
	DEFW    0600H 		; IMM
	DEFW    0B06H 		; ABS
	DEFW    1E0EH 		; (ZPG),Y
	DEFW    2208H 		; ZPG,X
	DEFW    2F12H 		; ABS,Y
	DEFW    2B10H 		; ABS,X
BBBTBL  DEFW    0     		; INVALID
	DEFW    0E04H 		; ZPG
	DEFW    1502H 		; ACC
	DEFW    0B06H 		; ABS
	DEFW    260AH 		; ZPG,Y
	DEFW    2208H 		; ZPG,X
	DEFW    2F12H 		; ABS,Y
	DEFW    2B10H 		; ABS,X
DDDTBL  DEFW    0600H 		; IMM
	DEFW    0E04H 		; ZPG
	DEFW    0     		; INVALID
	DEFW    0B06H 		; ABS
	DEFW    260AH 		; ZPG,Y
	DEFW    2208H 		; ZPG,X
	DEFW    2F12H 		; ABS,Y
	DEFW    2B10H 		; ABS,X
BBXTBL  DEFW    0E04H 		; ZPG
	DEFW    0B06H 		; ABS
	DEFW    2208H 		; ZPG,X
	DEFW    2B10H 		; ABS,X
	DEFW	260AH		; ZPG,Y
CCTBL   DEFW    0600H 		; IMM
	DEFW    0E04H 		; ZPG
	DEFW    0     		; INVALID
	DEFW    0B06H 		; ABS
;
; BRANCH MASK TABLE
;
MSKTBL  DEFW    8026H 		; BPL
	DEFW    801EH 		; BMI
	DEFW    402EH 		; BVC
	DEFW    4032H 		; BVS
	DEFW    010EH 		; BCC
	DEFW    0112H 		; BCS
	DEFW    0222H 		; BNE
	DEFW    0216H 		; BEQ
;
; FLAG SET/RESET CODES
;
FLGTBL  DEFW    0135H  		; CLC
	DEFW    01B1H		; SEC
	DEFW    043DH		; CLI
	DEFW    04B9H		; SEI
	DEFW    4041H		; CLV
	DEFW    0000		; INVALID
	DEFW    0839H		; CLD
	DEFW    08B5H		; SED
;
; JUMP TABLES TO IMPLIED INSTRUCTIONS
;
IMPTBL  DEFW    PPHP  		; IMPLIED INSTR TABLE
	DEFW    PPLP
	DEFW    PPHA
	DEFW	PPLA
	DEFW    PDEY
	DEFW    PTAY
	DEFW    PINY
	DEFW    PINX
	DEFW    PTXA
	DEFW    PTAX
	DEFW    PDEX
	DEFW    PNOP
;
; JUMP TABLE TO ADDR MODE PROCESSORS
;
GETTBL  DEFW    PIMM  		; INSTR MODE TABLE
	DEFW    PACX
	DEFW    PZPG
	DEFW    PAB
	DEFW    PZX
	DEFW    PZY
	DEFW    PZIX
	DEFW    PZIY
	DEFW    PABX
	DEFW    PABY
;
; JUMP TABLES TO MULTI-MODE PROCESSORS
;
EVNTBL  DEFW    PASL  		; JUMPS TO PROCESSORS
	DEFW    PBTRL
	DEFW    PLSR
	DEFW    PROR
	DEFW    PSTXY
	DEFW    PLDXY
	DEFW    PDCY
	DEFW    PICX
ODDTBL  DEFW    PORA
	DEFW    PAND
	DEFW    PEOR
	DEFW    PADC
	DEFW    PSTA
	DEFW    PLDA
	DEFW    PCMP
	DEFW    PSBC
;
; MNEMONIC ASCII CODES (PACKED INTO 2 BYTES)
;
MNMTBL  DEFW    0483H  		; MNEMONIC TABLE
	DEFW    05C4H
	DEFW    066CH
	DEFW    0863H 		; BCC
	DEFW    0873H
	DEFW    08B1H
	DEFW    0934H
	DEFW    09A9H
	DEFW    09C5H
	DEFW    0A0CH
	DEFW    0A4BH
	DEFW    0AC3H
	DEFW    0AD3H
	DEFW    0D83H 		; CLC
	DEFW    0D84H
	DEFW    0D89H
	DEFW    0D96H
	DEFW    0DB0H
	DEFW    0E18H
	DEFW    0E19H
	DEFW    10A3H		; DEC
	DEFW    10B8H
	DEFW    10B9H
	DEFW    15F2H		; EOR
	DEFW    25C3H		; INC
	DEFW    25D8H
	DEFW    25D9H
	DEFW    29B0H		; JMP
	DEFW    2A72H
	DEFW    3081H		; LDA
	DEFW    3098H
	DEFW    3099H
	DEFW    3272H
	DEFW    39F0H		; NOP
	DEFW    3E41H		; ORA
	DEFW    4101H		; PHA
	DEFW    4110H
	DEFW    4181H
	DEFW    4190H
	DEFW    49ECH		; ROL
	DEFW    49F2H
	DEFW    4A89H
	DEFW    4A93H
	DEFW    4C43H		; SBC
	DEFW    4CA3H
	DEFW    4CA4H
	DEFW    4CA9H
	DEFW    4E81H
	DEFW    4E98H
	DEFW    4E99H
	DEFW    5038H		; TAX
	DEFW    5039H
	DEFW    5278H
	DEFW    5301H
	DEFW    5313H
	DEFW    5321H
;
; ADDRESS MODE PRINT TABLE
;
AMDTBL  DEFM    ' $1    !'     ; ADDR MODE TABLE...REL
	DEFM    ' #$1   !'     ; IMMEDIATE
	DEFM    ' $21  !!'     ; ABS
	DEFM    ' $1    !'     ; ZPG
	DEFM    '        '     ; IMPLIED
	DEFM    ' A      '     ; ACCUM
	DEFM    ' ($1,X)!'     ; (ZPG,X)
	DEFM    ' ($1),Y!'     ; (ZPG),Y
	DEFM    ' $1,X  !'     ; ZPG,X
	DEFM    ' $1,Y  !'     ; ZPG,Y
	DEFM    ' $21,X!!'     ; ABS,X
	DEFM    ' $21,Y!!'     ; ABS,Y
	DEFM    ' ($21)!!'     ; INDIRECT
;
; THAT'S ALL!
;
	END
